package Eve;

import Util.FolderCreator;

import java.io.*;
import java.util.HashSet;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

public abstract class Eve {

    public final static String    MAIN_DIR    = ".\\main\\";
    public final static String    CIPHER_DIR  = ".\\cipher text\\";
    public final static String    KEYS_DIR   = ".\\keys\\";
       
    public final static char      START_SYMBOL = 'a';
    public final static char      END_SYMBOL = 'z';
    public final static int       N = END_SYMBOL - START_SYMBOL + 1;

    protected HashSet<String> m_processedFiles;

    public Eve(){        
        FolderCreator.createFolders();
        m_processedFiles = new HashSet<String>();
    }

    /**
     * Saves the key to file 'filename'-eve.key
     * @param filename  The filename.
     * @param key       The key.
     */
    protected static void saveKey(String filename,char[] key){
        byte[] message = new byte[2*N];
        for (int i=0; i<N; i++){
            message[2*i] = (byte)(key[i] & 0xFF);
            message[2*i+1] = '\n';
        }

        try {
            FileOutputStream fos = new FileOutputStream(KEYS_DIR+"\\"+filename+"-eve.key");
            fos.write(message);
            fos.close();
        }
        catch (IOException e) {
            System.out.println("Error saving the key to file, key is:");
            System.out.println(message);
        }
    }

    /**
     * Copies the 'in' file into the 'out' file 
     * @param in    The source.
     * @param out   The target.
     * @throws java.io.IOException  An error accessing the files
     */
    protected final void copyFile(File in, File out) throws IOException {
        FileChannel destinationChannel = new FileOutputStream(out).getChannel();
        FileChannel sourceChannel = new FileInputStream(in).getChannel();
        FileLock destinationLock=destinationChannel.lock();
        FileLock sourceLock=sourceChannel.lock(0l,Long.MAX_VALUE,true);

        sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
        
        sourceLock.release();
        destinationLock.release();
        sourceChannel.close();
        destinationChannel.close();

    }

    public abstract void run();
    public abstract char[] crack(String filename) throws IOException;
}


